<?php

namespace Vozminoski\StoreBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;


/**
 * Product
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Vozminoski\StoreBundle\Entity\ProductRepository")
 */
class Product
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;

    /**
     * @var string
     *
     * @ORM\Column(name="description", type="string")
     */
    private $description;

    /**
     * @var string
     *
     * @ORM\Column(name="composition", type="string")
     */
    private $composition;

    /**
     * @var string
     *
     * @ORM\Column(name="discount", type="string")
     */
    private $discount;

    /**
     * @var float
     *
     * @ORM\Column(name="price", type="float")
     */
    private $price;

    /**
     * @var integer
     *
     * @ORM\Column(name="sort_order", type="smallint")
     */
    private $order;

    /**
     * @var boolean
     *
     * @ORM\Column(name="is_active", type="boolean")
     */
    private $is_active;

    /**
     * @ORM\ManyToOne(targetEntity="Catalog", inversedBy="products")
     * @ORM\JoinColumn(name="catalog_id", referencedColumnName="id")
     */
    protected $category;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    public $path;

    /**
     * @Assert\File(maxSize="6000000")
     */
    public $file;


    /**
     * @ORM\ManyToMany(targetEntity="Color")
     * @ORM\JoinTable(name="products_colors",
     * joinColumns={@ORM\JoinColumn(name="product_id", referencedColumnName="id")},
     * inverseJoinColumns={@ORM\JoinColumn(name="color_id", referencedColumnName="id")}
     * )
     **/
    private $colors;


    /**
     * @ORM\ManyToMany(targetEntity="Size")
     * @ORM\JoinTable(name="products_size",
     * joinColumns={@ORM\JoinColumn(name="product_id", referencedColumnName="id")},
     * inverseJoinColumns={@ORM\JoinColumn(name="size_id", referencedColumnName="id")}
     * )
     **/
    private $sizes;

    /**
     * @ORM\OneToMany(targetEntity="OrderItems", mappedBy="product")
     */
    protected $orders;

    /**
     * @ORM\OneToMany(targetEntity="Image", mappedBy="product")
     */
    protected $images;

    public function getAbsolutePath()
    {
        return null === $this->path ? null : $this->getUploadRootDir() . '/'.$this->path;
    }

    public function getWebPath()
    {
        return null === $this->path ? null : '/' . $this->getUploadDir() . '/'.$this->path;
    }

    protected function getUploadRootDir()
    {
        return __DIR__.'/../../../../web/'.$this->getUploadDir();
    }

    protected function getUploadDir()
    {
        return 'uploads/product';
    }

    public function upload()
    {
        if (null === $this->file) {
            return;
        }

        $this->file->move($this->getUploadRootDir(), $this->file->getClientOriginalName());
        $this->path = $this->file->getClientOriginalName();
        $this->file = null;
    }

    /**
     * Get composition from request
     *
     * @param $requestData
     * @return Product
     */
    public function getCompositionFromRequest($requestData)
    {
        $preparedToSerializeData = array();
        if (is_array($requestData) && count($requestData)) {
            foreach($requestData as $value) {
                if ($value['name'] && $value['value']) {
                    $preparedToSerializeData[$value['name']] =  $value['value'];
                }
            }
        }

        $this->setComposition(serialize($preparedToSerializeData));
        return $this;
    }

    /**
     * Get discount from request
     *
     * @param $requestData
     * @return Product
     */
    public function getDiscountFromRequest($requestData)
    {
        $preparedToSerializeData = array();
        if (is_array($requestData) && count($requestData)) {
            foreach($requestData as $value) {
                if ($value['quantity'] && $value['value'] && isset($value['type'])) {
                    $preparedToSerializeData[] =  $value;
                }
            }
        }

        $this->setDiscount(serialize($preparedToSerializeData));
        return $this;
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Product
     */
    public function setName($name)
    {
        $this->name = $name;
    
        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set description
     *
     * @param string $description
     * @return Product
     */
    public function setDescription($description)
    {
        $this->description = $description;
    
        return $this;
    }

    /**
     * Get description
     *
     * @return string 
     */
    public function getDescription()
    {
        return $this->description;
    }

    /**
     * Set price
     *
     * @param float $price
     * @return Product
     */
    public function setPrice($price)
    {
        $this->price = $price;
    
        return $this;
    }

    /**
     * Get price
     *
     * @return float 
     */
    public function getPrice()
    {
        return $this->price;
    }

    /**
     * Set order
     *
     * @param integer $order
     * @return Product
     */
    public function setOrder($order)
    {
        $this->order = $order;
    
        return $this;
    }

    /**
     * Get order
     *
     * @return integer 
     */
    public function getOrder()
    {
        return $this->order;
    }

    /**
     * Set is_active
     *
     * @param boolean $isActive
     * @return Product
     */
    public function setIsActive($isActive)
    {
        $this->is_active = $isActive;
    
        return $this;
    }

    /**
     * Get is_active
     *
     * @return boolean 
     */
    public function getIsActive()
    {
        return $this->is_active;
    }

    /**
     * Set category
     *
     * @param \Vozminoski\StoreBundle\Entity\Catalog $category
     * @return Product
     */
    public function setCategory(\Vozminoski\StoreBundle\Entity\Catalog $category = null)
    {
        $this->category = $category;
    
        return $this;
    }

    /**
     * Get category
     *
     * @return \Vozminoski\StoreBundle\Entity\Catalog 
     */
    public function getCategory()
    {
        return $this->category;
    }

    /**
     * Set path
     *
     * @param string $path
     * @return Product
     */
    public function setPath($path)
    {
        $this->path = $path;
    
        return $this;
    }

    /**
     * Get path
     *
     * @return string 
     */
    public function getPath()
    {
        return $this->path;
    }

    function __construct()
    {
        $this->colors = new \Doctrine\Common\Collections\ArrayCollection();
        $this->sizes = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add colors
     *
     * @param \Vozminoski\StoreBundle\Entity\Color $colors
     * @return Product
     */
    public function addColor(\Vozminoski\StoreBundle\Entity\Color $colors)
    {
        $this->colors[] = $colors;
    
        return $this;
    }

    /**
     * Remove colors
     *
     * @param \Vozminoski\StoreBundle\Entity\Color $colors
     */
    public function removeColor(\Vozminoski\StoreBundle\Entity\Color $colors)
    {
        $this->colors->removeElement($colors);
    }

    /**
     * Get colors
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getColors()
    {
        return $this->colors;
    }

    /**
     * Add sizes
     *
     * @param \Vozminoski\StoreBundle\Entity\Size $sizes
     * @return Product
     */
    public function addSize(\Vozminoski\StoreBundle\Entity\Size $sizes)
    {
        $this->sizes[] = $sizes;
    
        return $this;
    }

    /**
     * Remove sizes
     *
     * @param \Vozminoski\StoreBundle\Entity\Size $sizes
     */
    public function removeSize(\Vozminoski\StoreBundle\Entity\Size $sizes)
    {
        $this->sizes->removeElement($sizes);
    }

    /**
     * Get sizes
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getSizes()
    {
        return $this->sizes;
    }

    /**
     * Set composition
     *
     * @param string $composition
     * @return Product
     */
    public function setComposition($composition)
    {
        $this->composition = $composition;
    
        return $this;
    }

    /**
     * Get composition
     *
     * @return string 
     */
    public function getComposition()
    {
        return $this->composition;
    }


    /**
     * Get composition
     *
     * @return string
     */
    public function getUnserializeComposition()
    {
        return $this->composition ? unserialize($this->composition) : array();
    }

    /**
     * Add orders
     *
     * @param \Vozminoski\StoreBundle\Entity\Orders $orders
     * @return Product
     */
    public function addOrder(\Vozminoski\StoreBundle\Entity\Orders $orders)
    {
        $this->orders[] = $orders;
    
        return $this;
    }

    /**
     * Remove orders
     *
     * @param \Vozminoski\StoreBundle\Entity\Orders $orders
     */
    public function removeOrder(\Vozminoski\StoreBundle\Entity\Orders $orders)
    {
        $this->orders->removeElement($orders);
    }

    /**
     * Get orders
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getOrders()
    {
        return $this->orders;
    }

    /**
     * Set discount
     *
     * @param string $discount
     * @return Product
     */
    public function setDiscount($discount)
    {
        $this->discount = $discount;
    
        return $this;
    }

    /**
     * Get discount
     *
     * @return string 
     */
    public function getDiscount()
    {
        return $this->discount;
    }

    /**
     * Get price per N items
     *
     * @param $count
     * @return mixed
     */
    public function getPricePerNumberItems($count)
    {
        $maximumDiscountPrice = $this->getMaximumDiscountPrice($count);
        return $count * ($maximumDiscountPrice ? $maximumDiscountPrice : $this->getPrice() );
    }

    /**
     * Get maximum discount price
     *
     * @param $count
     * @return float|null
     */
    protected function getMaximumDiscountPrice($count)
    {
        $discountsData = unserialize($this->getDiscount());
        $maxDiscount = null;
        $discountQuantity = 0;
        foreach ($discountsData as $discount) {
            if ($count >= $discount['quantity'] && $discountQuantity < $discount['quantity']) {
                $discountQuantity = $discount['quantity'];
                if ($discount['type'] == 1) {
                    $maxDiscount = $this->getPrice() - $discount['value'];
                } else {
                    $maxDiscount = $this->getPrice() - ($this->getPrice() / 100 * $discount['value']);
                }
            }
        }
        return $maxDiscount;
    }


    /**
     * Get composition
     *
     * @return string
     */
    public function getUnserializeDiscount()
    {
        return $this->discount ? unserialize($this->discount) : array();
    }

    /**
     * Add images
     *
     * @param \Vozminoski\StoreBundle\Entity\Image $images
     * @return Product
     */
    public function addImage(\Vozminoski\StoreBundle\Entity\Image $images)
    {
        $this->images[] = $images;
    
        return $this;
    }

    /**
     * Remove images
     *
     * @param \Vozminoski\StoreBundle\Entity\Image $images
     */
    public function removeImage(\Vozminoski\StoreBundle\Entity\Image $images)
    {
        $this->images->removeElement($images);
    }

    /**
     * Get images
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getImages()
    {
        return $this->images;
    }
}